<template>
  <div id="chuankou">
    <span>串口：<font v-if="showErr" color="#f00">请选择串口</font></span>
    <select class="select" v-model="select">
      <option :value="i.path" v-for="i in coms" :key="i.path">{{ i.path }} {{ i.manufacturer}}</option>
    </select>
    <span>波特率：</span>
    <select class="select" v-model="selectRate">
      <option :value="i" v-for="i in rates" :key="i">{{ i }}</option>
    </select>
    <div v-if="show">
      <span>字节：</span>
      <select class="select" v-model="dataBit">
        <option :value="i" v-for="i in [8,6,7,5]" :key="i">{{ i }}</option>
      </select>
      <span> 停止位：</span>
      <select class="select" v-model="stop">
        <option :value="i" v-for="i in [2,1]" :key="i">{{ i }}</option>
      </select>
      <span> 解码方式：</span>
      <select class="select" v-model="resolve">
        <option :value="i" v-for="i in ['hex','ascii', 'utf8', 'base64', 'binary']" :key="i">{{ i }}</option>
      </select>
      <span> 解析方式：</span>
      <select class="select" v-model="pipe">
        <option :value="i" v-for="i in ['折行显示','原始数据']" :key="i">{{ i }}</option>
      </select>
    </div>
    <button v-if="!isOpen" @click="connect" :disabled="!select || loading"><i class="el-icon-loading" v-if="loading"></i>  打开</button>
    <button v-if="isOpen" @click="unconnect" :disabled="loading"><i class="el-icon-loading" v-if="loading"></i> 断开</button>
    <button @click="show = !show">{{ show? '收起' : '高级设置'}}</button>
  </div>
</template>
<script>
module.exports = {
  mounted () {
    this.timer = setInterval(() => {
      this.getComs()
    }, 1000);
  },
  data(){
    return {
      loading: false,
      isOpen: false,
      show: false,
      timer: null,
      rates: [ 115200,57600,38400,19200,9600,4800,2400,1800,1200,600,300,200,150,134,110,75,50 ],
      coms:[],
      err: "",
      select: "",
      selectRate: 9600,
      dataBit: 8,
      stop: 1,
      resolve: "utf8",
      port: null,
      showErr: false,
      pipe: '折行显示'
    }
  },
  destroyed () {
    this.timer && clearInterval(this.timer)
    this.unconnect()
  },
  methods: {
    close(){
      this.show = false
    },
    getComs(){
      this.$serialPort.list().then(res => {
        this.coms = res
        if(!res.length) return this.$emit('empty')
      }).catch(err => {
        this.$emit('error', err)
        this.coms = [];
      })
    },
    unconnect(){
      if(this.port){
        this.loading = true
        this.port.close(() =>{
          this.isOpen = false;
          this.port = null;
          this.onData('连接关闭')
          this.loading = false
        })
      }
    },
    error(err){
      this.$emit('connectError', err)
      this.isOpen = false
    },
    connect(){
      if(!this.select) {
        return this.showErr = true
      }else{
        this.showErr = false
      }
      this.loading = true
      this.port = new this.$serialPort(this.select, {
        baudRate: this.selectRate,
        stopBits: this.stop,
        dataBits: this.dataBit
      }, err => {
        this.loading = false
        if(err) return this.error(err);
        this.open()
      })
      if(this.pipe == '折行显示'){
        const parser = this.port.pipe(new Readline());
        parser.on('data', data => {
          this.onData(data)
        })
      }else{
        this.port.on('data', data => {
          this.onData(data)
        })
      }
    },
    sender(msg, encoding){
      this.port.write(msg, encoding|| '', err => {
        if(err) return this.$emit('error', err)
      })
    },
    open(){
      this.onData('连接打开')
      this.isOpen = true
    },
    onData(data){
      message = ['连接打开', '连接关闭'].includes(data) ? data : new Buffer(data)
      this.$emit('message', message.toString(this.resolve).toUpperCase())
    }
  },
  watch: {
    select(val){
      this.$emit('select', val)
    },
    isOpen(val){
      this.$emit('open', val)
    }
  }
}
</script>
<style lang="less">
#chuankou{
  padding: 10px;
  color: #000;
  select{
    width: 100%;
    display: block;
    margin: 10px 0;
    margin-top: 2px;
  }
}
</style>